Skip to content

feat(memory): project summary + last-3-sessions in SessionStart resume#71

Closed
fazleelahhee wants to merge 1 commit into
mainfrom
feat/auto-project-summary-on-session-start
Closed

feat(memory): project summary + last-3-sessions in SessionStart resume#71
fazleelahhee wants to merge 1 commit into
mainfrom
feat/auto-project-summary-on-session-start

Conversation

@fazleelahhee
Copy link
Copy Markdown
Contributor

Summary

Each fresh Claude Code conversation used to open with the model knowing
decisions from prior sessions but having no idea what the project
actually IS
— every chat re-derived the basics from a context_search
or a manual recap. The SessionStart resume only carried the single
most-recent
session rollup, so multi-day work threads lost continuity.

This PR fixes both:

  1. Persistent project summary — extractively built from
    README/pyproject + indexed chunks + recent code_areas, stored in
    memory.db, and prepended to every SessionStart resume.
  2. Last 3 prior-session rollups (was 1) so multi-day work shows up
    in the resume.

Changes

  • memory.db v4 — new project_summary table (additive migration)
  • context_engine.memory.project_summary — extractive builder, no
    LLM dependency. Pitch ← README/pyproject, tech_stack ← extension
    tally of indexed chunks, recent_focus ← code_areas
  • cce summarize CLI (--force to bypass 7-day TTL)
  • cce init runs the summary after the initial index so the
    first SessionStart already has data
  • build_session_resume prepends the summary block + bumps prior
    sessions from 1 → 3 + degrades gracefully if the v4 table is missing

Tests

19 new cases in tests/memory/test_project_summary.py:

  • schema migration
  • upsert / load / is_stale round-trip
  • pitch extraction (README, pyproject fallback, empty)
  • tech_stack tally
  • recent_focus ordering
  • format_summary_block omits empty sections
  • resume includes the summary block, shows last 3 of 4 sessions,
    uses singular header when exactly 1, returns empty on a virgin
    project, tolerates a missing v4 table

Deferred to a follow-up

  • Mirror the same summary block into the MCP context-engine-init
    bootstrap prompt so Codex CLI (no hook support) gets the same
    content via its system-prompt path. The data and the formatter are
    ready — only the wiring is left.

Verification

  • pytest -n 4894 passed, 1 skipped, 0 failed
  • ruff check on every changed file → clean

Test plan

  • cce init on a fresh project — see "Project summary captured"
    line at the end of init output
  • cce summarize shows the captured block
  • Restart Claude Code in the project — confirm the SessionStart
    injection includes:
    Project summary
    Stack:
    Recent focus:
  • After 3 sessions land rollups, confirm the next SessionStart
    shows all 3 (not just the latest)
  • An older memory.db (pre-v4) opens cleanly and the resume falls
    back to the previous shape

Adds a persistent, per-project summary that SessionStart injects at the
top of every new Claude Code conversation, so each fresh session opens
with a clear picture of what the project IS — not just what was decided
last week. Pairs with a bump from 1 → 3 prior-session rollups so the
"last 2-3 sessions of work" context the user asked for actually
surfaces.

What's added

- memory.db v4: new `project_summary` table (one row per project) with
  pitch, tech_stack, recent_focus, source_file_count, generated_at_epoch.
  Migration is purely additive — old dbs upgrade in place on the next
  `connect()`. The migration path doesn't need sqlite-vec, so users
  without it still get v4.

- `context_engine.memory.project_summary` — extractive builder with no
  LLM dependency:
    * pitch     ← first substantive line of README.md (HTML/badge
                  stripped), fallback to pyproject.toml's
                  [project].description
    * tech_stack ← extension tally across the indexed chunks
                   ("Python (124), TypeScript (38), Markdown (12)")
    * recent_focus ← top 5 file_paths from the code_areas table,
                     most-recent first, with each description capped
                     at 100 chars
  Plus upsert / load / is_stale / format_summary_block helpers.

- `cce summarize` — manual refresh, `--force` to bypass the 7-day
  staleness check.

- `cce init` now calls `_refresh_project_summary` after the initial
  index so the summary lands before the first SessionStart fires.

- `build_session_resume` rewritten:
    * prepends the project summary block when present
    * shows the last 3 sessions' rollups (was 1) — header switches to
      "Previous N sessions" when plural, "Previous session" when one
    * tolerates an old db that's missing the v4 table (skips the block
      instead of raising)

- Tests (new file):
    * schema migration creates table on fresh and upgrades existing
    * upsert round-trips, replaces existing, returns None when absent
    * pitch extraction from README, fallback to pyproject, empty when
      neither present
    * tech_stack tally
    * recent_focus ordering
    * format_summary_block omits empty sections
    * build_session_resume:
        - includes the new summary block
        - shows the last 3 of 4 prior sessions and drops the oldest
        - uses singular "Previous session" with exactly 1
        - returns empty string on a virgin project
        - degrades gracefully when project_summary table is missing

Not in this PR (follow-up)

- Mirroring the same summary block into the MCP `context-engine-init`
  bootstrap prompt so Codex CLI (which doesn't have hooks) gets the
  same content via its system-prompt path. The data and the formatter
  are now ready for that wiring.

Suite: 894 passed, 1 skipped, 0 failed. Ruff clean.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant